package g

import (
	"bufio"
	"bytes"
	"encoding/binary"
)

// Encode 将消息编码
func Encode(message string) ([]byte, error) {
	// 读取消息的长度，转换成int32类型(占4个字节)
	var length = int32(len(message))  //比如客户端发送的“Hello, Hello. How are you?”这个消息的长度为26
	var pkg = new(bytes.Buffer)
	// 写入消息头 小端
	err := binary.Write(pkg, binary.LittleEndian, length)
	if err != nil {
		return nil, err
	}
	// 写入消息实体
	err = binary.Write(pkg, binary.LittleEndian, []byte(message))
	if err != nil {
		return nil, err
	}
	// pkg.Bytes: [26 0 0 0 72 101 108 108 111 44 32 72 101 108 108 111 46 32 72 111 119 32 97 114 101 32 121 111 117 63]
	//可以看到前4个字节存的是长度，后面接的是数据部分，刚好是26个字节长度
	return pkg.Bytes(), nil
}

// Decode 解码消息
func Decode(reader *bufio.Reader) (string, error) {
	// 读取消息的长度
	lengthByte, _ := reader.Peek(4) // 读取前4个字节的数据：[26 0 0 0]
	// Peek()方法不会移动读取的位置，就是说使用Peek()读取一次指定大小的数据后，下次再读取时还是从原先的位置读取
	lengthBuff := bytes.NewBuffer(lengthByte)
	var length int32
	err := binary.Read(lengthBuff, binary.LittleEndian, &length)  //得到长度：26
	if err != nil {
		return "", err
	}
	// Buffered返回缓冲中现有的可读取的字节数。
	if int32(reader.Buffered()) < length+4 {
		return "", err
	}

	// 读取真正的消息数据
	pack := make([]byte, int(4+length))
	_, err = reader.Read(pack)
	if err != nil {
		return "", err
	}
	return string(pack[4:]), nil
}
